package com.binance.basedao.mybatis;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <b>Description:</b>〈Model bean 工具类〉<br/>
 * @author hongchaoMao <br/>
 *         Create date: 2017/9/18
 * @version v1.0.0
 */
public class ModelUtils
{
    
    public static Map<String, Property> getProperties(Object object, ColumnTarget columnTarget) throws IllegalArgumentException,
            IllegalAccessException, InvocationTargetException
    {
        Class<?> modelClass = object.getClass();
        Map<String, Property> properties = getProperties(modelClass, columnTarget);
        Map<String, Property> results = new HashMap<>(properties.size());
        for (Map.Entry<String, Property> propertyEntry : properties.entrySet()) {
            Property property = propertyEntry.getValue();
            if (columnTarget == ColumnTarget.INSERT || columnTarget == ColumnTarget.UPDATE || columnTarget == ColumnTarget.WHERE) {
                if (property.isNullValue(object)) { // 空值忽略
                    continue;
                }
            }
            results.put(propertyEntry.getKey(), property);
        }
        return results;
    }
    
    /**
     * @param columnTarget 允许为null
     * @return
     */
    public static Map<String, Property> getProperties(Class<?> modelClass, ColumnTarget columnTarget)
    {
        PropertyDescriptor[] propDescriptors = getPropertiesHelper(modelClass, true, true);
        Map<String, Property> properties = new HashMap<>(propDescriptors.length);
        for (PropertyDescriptor propertyDescriptor : propDescriptors) {
            Property property = new Property(modelClass, propertyDescriptor);
            if (property.isTransient()) {
                continue;
            }
            if (property.isUnableForColumnTarget(columnTarget)) {
                continue;
            }
            if (columnTarget == ColumnTarget.ORDER) {
                if (!property.isOrderColumn()) { // 仅保留ordercolumn
                    continue;
                }
            }
            properties.put(property.getName(), property);
        }
        return properties;
    }

    public static PropertyDescriptor[] getBeanProperties(Class type) {
        return getPropertiesHelper(type, true, true);
    }

    public static PropertyDescriptor[] getBeanGetters(Class type) {
        return getPropertiesHelper(type, true, false);
    }

    public static PropertyDescriptor[] getBeanSetters(Class type) {
        return getPropertiesHelper(type, false, true);
    }

    private static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) {
        try {
            BeanInfo info = Introspector.getBeanInfo(type, Object.class);
            PropertyDescriptor[] all = info.getPropertyDescriptors();
            if (read && write) {
                return all;
            } else {
                List<PropertyDescriptor> properties = new ArrayList<>(all.length);
                for (PropertyDescriptor pd : all) {
                    if (read && pd.getReadMethod() != null || write && pd.getWriteMethod() != null) {
                        properties.add(pd);
                    }
                }
                return properties.toArray(new PropertyDescriptor[0]);
            }
        } catch (IntrospectionException var8) {
            throw new RuntimeException(var8);
        }
    }
    
}
